#include "pch.h"
#include <boost/asio.hpp>
#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <cmath>
#include <iomanip>
#include <map>

using boost::asio::ip::tcp;

// 新建目录
bool create_path(std::string dz) {
    std::filesystem::path directory_path = dz;
    if (std::filesystem::exists(directory_path)) {
        return true;
    } else {
        if (std::filesystem::create_directory(directory_path)) {
            return true;
        } else {
            std::cerr << "创建目录:" << dz << " 失败" << std::endl;
            return false;
        }
    }
}

// 替换后的 tick_ai_api 函数
int tick_ai_api(int flag, int num, double* data, int &result0, int &result1) {
    try {
        boost::asio::io_context io_context;
        tcp::resolver resolver(io_context);
        auto endpoints = resolver.resolve("127.0.0.1", "8888");
        tcp::socket socket(io_context);
        boost::asio::connect(socket, endpoints);

        std::vector<char> buffer(sizeof(int) * 2 + sizeof(double) * num);
        std::memcpy(buffer.data(), &flag, sizeof(int));
        std::memcpy(buffer.data() + sizeof(int), &num, sizeof(int));
        std::memcpy(buffer.data() + sizeof(int) * 2, data, sizeof(double) * num);

        boost::asio::write(socket, boost::asio::buffer(buffer));

        int response[2];
        boost::asio::read(socket, boost::asio::buffer(response, sizeof(response)));

        result0 = response[0];
        result1 = response[1];

        socket.close();
        return 0;
    } catch (std::exception& e) {
        std::cerr << "错误：网络通信失败 - " << e.what() << std::endl;
        return -1;
    }
}

// 读取 CSV 文件
std::vector<std::vector<std::string>> read_csv(std::string dz) {
    std::ifstream csv_file(dz.c_str());
    std::vector<std::vector<std::string>> data;
    std::string line;
    while (std::getline(csv_file, line)) {
        std::vector<std::string> row;
        std::stringstream ss(line);
        std::string cell;
        while (std::getline(ss, cell, ',')) {
            row.push_back(cell);
        }
        data.push_back(row);
    }
    return data;
}

// 获取日期时间
std::string get_date_time() {
    auto now_0 = std::chrono::system_clock::now();
    std::time_t now_c = std::chrono::system_clock::to_time_t(now_0);
    std::tm now_tm = *std::localtime(&now_c);
    char text[80] = {0};
    snprintf(text, sizeof(text), "%02d点%02d分%02d秒 %02d月%02d日", now_tm.tm_hour, now_tm.tm_min, now_tm.tm_sec, now_tm.tm_mon + 1, now_tm.tm_mday);
    return std::string(text);
}

// 获取日期间隔
int date_between(std::string date1, std::string date2) {
    if (date1.length() != 8 || date2.length() != 8) {
        return 0;
    }
    std::tm tm1 = {};
    std::tm tm2 = {};
    std::istringstream ss1(date1);
    ss1 >> std::get_time(&tm1, "%Y%m%d");
    std::istringstream ss2(date2);
    ss2 >> std::get_time(&tm2, "%Y%m%d");
    auto tp1 = std::chrono::system_clock::from_time_t(std::mktime(&tm1));
    auto tp2 = std::chrono::system_clock::from_time_t(std::mktime(&tm2));
    auto duration = tp2 - tp1;
    auto days = std::chrono::duration_cast<std::chrono::duration<int, std::ratio<86400>>>(duration);
    return days.count();
}

// 获取文件列表
int get_file_list(const std::filesystem::path& path, std::vector<std::string>& lists) {
    if (!std::filesystem::exists(path)) {
        std::cout << "路径不存在：" << path << '\n';
        return -1;
    }
    if (!std::filesystem::is_directory(path)) {
        std::cout << "给定路径不是一个目录：" << path << '\n';
        return -1;
    }
    for (const auto& entry : std::filesystem::directory_iterator(path)) {
        lists.push_back(entry.path().filename());
    }
    std::sort(lists.begin(), lists.end());
    return lists.size();
}

// 解析合约代码字符串
int instrument_to_type(std::string str, std::string& data_type, std::string& data_name, std::string& data_to) {
    if (str.empty()) {
        return -1;
    }
    int i = 0, j = 0, k = 0, l = 0;
    for (i = 0; i < str.length(); i++) {
        if ((str[i] > 64 && str[i] < 91) || (str[i] > 96 && str[i] < 123)) {
        } else {
            break;
        }
    }
    for (j = i; j < str.length(); ++j) {
        if (str[j] > 47 && str[j] < 58) {
        } else {
            break;
        }
    }
    if (i == 0 || j == i) {
        return -2;
    }
    if (j == str.length() || str[j] == '.') {
        data_type.append(str, 0, i);
        data_name.append(str, 0, j);
        return 0;
    }
    for (k = j; k < str.length(); k++) {
        if (str[k] == 45 || str[k] == 67 || str[k] == 80) {
        } else {
            break;
        }
    }
    for (l = k; l < str.length(); ++l) {
        if (str[l] > 47 && str[l] < 58) {
        } else {
            break;
        }
    }
    if (k == j || l == k) {
        return -3;
    }
    if (l == str.length() || str[l] == '.') {
        data_type.append(str, 0, k);
        data_name.append(str, 0, l);
        data_to.append(str, 0, j);
        return 1;
    }
    return -4;
}

// 事件类
    void class_event::insert(std::function<void()> func, int key) {
        std::unique_lock<std::mutex> lock(mtx);
        funcs_map[key] = func;
    }
    void class_event::pop(int key) {
        std::unique_lock<std::mutex> lock(mtx);
        funcs_map.erase(key);
    }
    void class_event::notify() {
        for (auto& func_map : funcs_map) {
            std::unique_lock<std::mutex> lock(mtx);
            func_map.second();
        }
    }

// 线程池类
lambda_pool::lambda_pool() {
        size_t num = std::thread::hardware_concurrency();
        flag = true;
        for (size_t i = 0; i < num; ++i) {
            threads.emplace_back([this]() { circle(); });
        }
    }
lambda_pool::~lambda_pool() {
        {
            std::lock_guard<std::mutex> lock(mtx);
            flag = false;
        }
        cv.notify_all();
        for (auto& thread : threads) {
            thread.join();
        }
    }
    void lambda_pool::circle() {
        while (true) {
            std::unique_lock<std::mutex> lock(mtx);
            cv.wait(lock, [this]() { return !functions.empty() || !flag; });
            if (functions.empty() && !flag) {
                break;
            }
            std::function<void()> func = std::move(functions.front());
            functions.pop();
            lock.unlock();
            func();
        }
    }
    void lambda_pool::insert(std::function<void()> func) {
        {
            std::lock_guard<std::mutex> lock(mtx);
            functions.push(std::move(func));
        }
        cv.notify_one();
    }

// 屏蔽浮点数溢出
double nomax(double x) {
    if (std::fabs(x) > 1e300) {
        return 0;
    }
    return x;
}

// 累积正态分布函数（CDF）
double cumulativeNormalDistribution(double x) {
    return 0.5 * (1.0 + std::erf(x / std::sqrt(2.0)));
}

// 计算布莱克-舒尔斯期权价格
double blackScholesPrice(double S, double K, double T, double r, double sigma, bool isCall) {
    double d1 = (std::log(S / K) + (r + 0.5 * sigma * sigma) * T) / (sigma * std::sqrt(T));
    double d2 = d1 - sigma * std::sqrt(T);
    return isCall ? S * cumulativeNormalDistribution(d1) - K * std::exp(-r * T) * cumulativeNormalDistribution(d2)
                  : K * std::exp(-r * T) * cumulativeNormalDistribution(-d2) - S * cumulativeNormalDistribution(-d1);
}

// 求解隐含波动率的函数
double impliedVolatility(double S, double K, double T, double C, bool isCall, double r, double sigma_low, double sigma_high, double tolerance, int max_iterations) {
    T /= 365.0;
    auto func = [&](double sigma) {
        return blackScholesPrice(S, K, T, r, sigma, isCall) - C;
    };
    double sigma_mid = (sigma_low + sigma_high) / 2.0;
    for (int i = 0; i < max_iterations; ++i) {
        double price_mid = blackScholesPrice(S, K, T, r, sigma_mid, isCall);
        if (std::fabs(price_mid - C) < tolerance) {
            return sigma_mid;
        }
        if ((blackScholesPrice(S, K, T, r, sigma_low, isCall) - C) * (price_mid - C) < 0) {
            sigma_high = sigma_mid;
        } else {
            sigma_low = sigma_mid;
        }
        sigma_mid = (sigma_low + sigma_high) / 2.0;
    }
    return -1.0;
}
